from dojo.models import Finding
from dojo.tools.trivy_operator.uniform_vulnid import UniformTrivyVulnID

DESCRIPTION_TEMPLATE = """{title}
**Fixed version:** {fixed_version}
"""

TRIVY_SEVERITIES = {
    "CRITICAL": "Critical",
    "HIGH": "High",
    "MEDIUM": "Medium",
    "LOW": "Low",
    "UNKNOWN": "Info",
}


class TrivyVulnerabilityHandler:
    def handle_vulns(self, labels, vulnerabilities, test):
        findings = []
        resource_namespace = labels.get("trivy-operator.resource.namespace", "")
        resource_kind = labels.get("trivy-operator.resource.kind", "")
        resource_name = labels.get("trivy-operator.resource.name", "")
        container_name = labels.get("trivy-operator.container.name", "")
        service = f"{resource_namespace}/{resource_kind}/{resource_name}"
        if container_name:
            service = f"{service}/{container_name}"
        for vulnerability in vulnerabilities:
            vuln_id = vulnerability.get("vulnerabilityID", "0")
            severity = TRIVY_SEVERITIES[vulnerability.get("severity")]
            references = vulnerability.get("primaryLink")
            mitigation = vulnerability.get("fixedVersion")
            fix_available = True
            if not vulnerability.get("fixedVersion"):
                fix_available = False
            package_name = vulnerability.get("resource")
            package_version = vulnerability.get("installedVersion")
            cvssv3_score = vulnerability.get("score")
            finding_tags = [resource_namespace]
            target_target = None
            target_class = None
            package_path = None

            if vulnerability.get("packageType"):
                package_type = vulnerability.get("packageType")
                finding_tags.append(package_type)

            if vulnerability.get("class"):
                target_class = vulnerability.get("class")
                finding_tags.append(target_class)

            if vulnerability.get("packagePath"):
                package_path = vulnerability.get("packagePath")

            if vulnerability.get("target"):
                target_target = vulnerability.get("target")

            if target_class in {"os-pkgs", "lang-pkgs"}:
                if package_path:
                    file_path = package_path
                elif target_target:
                    file_path = target_target
                else:
                    file_path = None
            else:
                file_path = None

            description = DESCRIPTION_TEMPLATE.format(
                title=vulnerability.get("title"), fixed_version=mitigation,
            )
            description += "\n**container.name:** " + container_name
            description += "\n**resource.kind:** " + resource_kind
            description += "\n**resource.name:** " + resource_name
            description += "\n**resource.namespace:** " + resource_namespace
            title = f"{vuln_id} {package_name} {package_version}"
            finding = Finding(
                test=test,
                title=title,
                severity=severity,
                references=references,
                mitigation=mitigation,
                component_name=package_name,
                component_version=package_version,
                cvssv3_score=cvssv3_score,
                description=description,
                static_finding=True,
                dynamic_finding=False,
                service=service,
                file_path=file_path,
                tags=[tag for tag in finding_tags if tag],
                fix_available=fix_available,
            )
            if vuln_id:
                finding.unsaved_vulnerability_ids = [UniformTrivyVulnID().return_uniformed_vulnid(vuln_id)]
            findings.append(finding)
        return findings
